home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / demos / 20 / tvxsrc / tvx_io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-07-19  |  42.9 KB  |  1,969 lines

  1. #include "tvx_defs.ic"
  2. #include "tvx_glbl.ic"
  3.  
  4. #define SWITCH '-'
  5. #define FILESEP '.'
  6.  
  7. #ifdef MSDOS
  8. #define TEMPEXT ".$$1"        /* name of temporary file */
  9. #define BACKEXT ".BAK"        /* name of backup file */
  10. #endif
  11.  
  12. #ifdef OSCPM
  13. #define TEMPEXT ".$$1"        /* name of temporary file */
  14. #define BACKEXT ".BAK"        /* name of backup file */
  15. #endif
  16.  
  17. #ifdef GEM_DOS
  18. #define TEMPEXT ".Z1X"        /* name of temporary file */
  19. #define BACKEXT ".BAK"        /* name of backup file */
  20.     extern long bios();
  21.  
  22.     static int st_res;
  23. #endif
  24.  
  25. #ifdef UNIX
  26. #define BACKEXT ".B"        /* name of backup file */
  27. #endif
  28.  
  29. #ifdef MICROSOFT_C
  30.   void exit();
  31. #endif
  32.  
  33.     FILE *fopen();
  34.  
  35. /* local globals (used by tv terminal driver section) */
  36.  
  37.     static int linptr; /* common "linot" */
  38.     static char linout[242];
  39.  
  40.     static char stemp[FNAMESIZE+1];
  41.  
  42. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  43.  
  44.     FILE IO section
  45.  
  46.    File handling algorithm:
  47.  
  48.     The original name specified on command line is called orig_file.
  49.     It will remain untouched throughout the editing session.  At the
  50.     very end (normal exit), it will be renamed to the ".BAK" name.
  51.  
  52.     source_file is the current name of the file with source.  It will
  53.     orignally be the same as orig_file, but may change to a generated
  54.     scratch name depending on the operating system.  source_file is
  55.     always the lastest fully written version of the file (like after
  56.     file beginning, for example). 
  57.  
  58.     work_file is the output file.  On normal exit, this is the
  59.     file renamed to dest_file.  On buffer beginning, it will be
  60.     moved to source_file, possibly after renameing.
  61.     
  62.     dest_file is the ultimate destination file.  This name is not
  63.     actually used until the final rename on normal exit.  It is
  64.     checked to be sure it is a valid name to be opened, however.
  65.  
  66.    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  67.  
  68. /* =============================>>> T_ABORT <<<============================= */
  69.   t_abort()
  70.   {    /* abort - close files, abort operation */
  71.  
  72.     char rply[4];
  73.  
  74.     tvclr();
  75.     ask("Abort, are you sure?◆ ",rply,1);
  76.     if (clower(rply[0]) != 'y')
  77.       {
  78.     verify(1);
  79.     return;
  80.       }
  81.     abort2();
  82.   }
  83.  
  84. /* =============================>>> ABORT2 <<<============================= */
  85.   abort2()
  86.   {
  87.     clobak();
  88.     tvclr();
  89.  
  90.     if (!newfil)
  91.     fclose(infile);
  92.     if (!rdonly)
  93.     fclose(outfile);
  94.  
  95.     if (strcmp(orig_file,source_file) != 0)
  96.       {
  97.     prompt("File begin used, intermediate edits in: ");
  98.     remark(source_file);
  99.       }
  100.     unlink(work_file);        /* delete the work file */
  101.  
  102.     reset();
  103.     quit();
  104.   }
  105.  
  106. /* =============================>>> FBEG   <<<============================= */
  107.   int fbeg()
  108.   { /* fbeg - go back to file top */
  109.  
  110.     SLOW int fbegv;
  111.  
  112.     if (rdonly)
  113.       {
  114.     tverrb("Can't: R/O");    /* can't do this for read only access */
  115.     return (FALSE);
  116.       }
  117.  
  118.     for (wtpage(1) ; rdpage() ; wtpage(1) )    /* write out rest */
  119.     ;
  120.  
  121.     if ((! newfil))
  122.       {
  123.     fclose(infile);            /* close source_file */
  124.       }
  125.     if (usecz)
  126.     fputc(ENDFILE,outfile);
  127.  
  128.     fclose(outfile);            /* close work_file */
  129.  
  130. /* files closed now, re-open */ 
  131.  
  132.     newfil = FALSE;        /* not a new file any more */
  133.  
  134.     strcpy(source_file,work_file);    /* new source file */
  135.     temp_name(work_file,FALSE);        /* make a new temporary name */
  136.  
  137.     if (!(infile = fopen(source_file,FILEREAD)))
  138.     goto l900;
  139.     else
  140.     ineof = FALSE;
  141.  
  142.     unlink(work_file);            /* get rid of previous copies */
  143.  
  144.     if (!(outfile = fopen(work_file,FILEWRITE)))
  145.       {
  146.     goto l900;
  147.       }
  148.  
  149.     fbegv=rdpage();        /* read in new buffer */
  150.     newscr();
  151.     return (fbegv);
  152.  
  153. l900: tverrb("Error re-opening");
  154.     return (FALSE);
  155.   }
  156.  
  157. /* =============================>>> FILE_EXIT <<<============================= */
  158.   file_exit()
  159.   { /* close the input and output files, rename */
  160.  
  161.     SLOW int i;
  162.  
  163.     if (!newfil)        /* don't close input if new file */
  164.       {
  165.     fclose(infile);
  166.       }
  167.  
  168.     while (!rdonly && !*dest_file)
  169.       {
  170.     remark("No name for output file has been specified.");
  171.     prompt("Enter new name for output file: ");
  172.     reply(dest_file,FNAMESIZE);
  173.       }
  174.  
  175.     if (!rdonly)    /* don't close output if read only access */
  176.       {
  177.     if (usecz)
  178.         fputc(ENDFILE,outfile);
  179. #ifdef SYSV
  180.     set_mode(work_file);
  181. #else
  182.     set_mode(outfile);        /* set output mode if can */
  183. #endif
  184.     fclose(outfile);
  185.  
  186.     /*    orig_file has the name to be renamed to .bak
  187.     work_file has the file name we want to be dest_name
  188.     */
  189.     if (strcmp(orig_file,dest_file) == 0)    /* make backup version */
  190.       {
  191.         strcpy(stemp,orig_file);
  192. #ifndef COMMA_BAK
  193. #ifdef XENIX286
  194.         i = rindx(stemp,'/') + 1;  /* index to real filename */
  195.         if (strlen(&stemp[i]) > 12) /* must be room for .B */
  196.           {
  197.         if (stemp[i]++ != '+')    /* change first char to + */
  198.             stemp[i] = '+';
  199.           }
  200.         else
  201. #endif
  202.         if ((i = rindx(stemp,FILESEP)) > 0)    /* see if extenstion */
  203.         scopy(BACKEXT,0,stemp,i);        /* make .bak */
  204.         else
  205.           {
  206.         scopy(BACKEXT,0,stemp,strlen(stemp));    /* just add on */
  207.           }
  208. #else
  209.         i = rindx(orig_file,'/')+1;
  210.         scopy(".,",0,stemp,i);
  211.         scopy(orig_file,i,stemp,strlen(stemp));
  212. #endif
  213.  
  214.         unlink(stemp);        /* delete previous generation */
  215.         ren_file(orig_file,stemp);        /* rename the file */
  216.         if (!makebackup)            /* don't want to keep old one */
  217.         unlink(stemp);    /* delete it if don't want backup file */
  218.       }
  219.  
  220.     if (strcmp(orig_file,source_file) != 0)    /* delete intermediate file */
  221.         unlink(source_file);
  222.  
  223.  
  224.     while (infile = fopen(dest_file,FILEREAD))    /* output exists? */
  225.       {
  226.         fclose(infile);
  227.         prompt("Output file "); prompt(dest_file);
  228.         prompt(" already exists.  Overwrite it? (y/n) ");
  229.         ureply(stemp,1);
  230.         if (*stemp == 'Y')
  231.           {
  232.         unlink(dest_file);
  233.         break;
  234.           }
  235.         prompt("Enter new name for output file: ");
  236.         reply(dest_file,FNAMESIZE);
  237.       }
  238.  
  239.     ren_file(work_file,dest_file);        /* finally, rename last file */
  240.       }
  241.  
  242.   }
  243.  
  244. /* =============================>>> FOPENX  <<<============================= */
  245.   fopenx(argc,argv)
  246.   int argc;
  247.   char *argv[];
  248.   {  /* open the input file
  249.     This routine picks up file name from the user, creates a backup
  250.     version in some appropriate manner, and opens the file for input
  251.     and output. */
  252.  
  253.     SLOW int iswval, iswbeg, argnum;
  254.     SLOW char ch, tmpc;
  255.     char rply[4];
  256.  
  257.     usebak = logdef;        /* if useing backup log file */
  258.  
  259.     if (argc <= 1)
  260.       {
  261.     remark("Usage: tvx filename [-b -i -l -o=f -r -s -w -# -x=c {-z}]");
  262. #ifdef FULLHELP
  263.     remark("");
  264.     starthelp();        /* print start help message */
  265.     prompt(" Options: "); remark(VERSION);
  266.     remark("  -[no]b : backup file   -[no]i : autoindent");
  267.     remark("  -[no]l : make command log file");
  268.     remark("  -o=outputfile          -r : read only");
  269.     remark("  -s : big save buff     -[no]w : word processing mode");
  270.     remark("  -# : set virtual window lines to #");
  271.     remark("  -x=commands");
  272.  
  273. #ifdef UNIX
  274.     remark("  {some options not available for unix}");
  275. #endif
  276. #endif
  277. #ifdef MSDOS
  278.     remark("  -[no]z : use control-z for end of file");
  279. #endif
  280. #ifdef GEM_DOS
  281.     remark("  -[no]z : use control-z for end of file");
  282.     remark("");
  283.     prompt("Press any key...◆");
  284.     reply(rply,1);
  285. #endif
  286.     remark("");
  287.     reset();
  288.     quit();
  289.       }
  290.  
  291.     newfil=                /* assume opening an old file */
  292.     rdonly = FALSE;            /* assume not read only */
  293.     makebackup = MAKE_BACKUP;        /* default value for make a backup */
  294.     blimit = BUFFLIMIT;
  295.  
  296.     for (argnum = 1 ; argnum < argc ; ++argnum)
  297.       {
  298.     strcpy(stemp,argv[argnum]);    /* pick up the file name or switch */
  299. REDO:
  300.     if (stemp[0] == SWITCH)        /* switch in form "/R filename" only */
  301.       {
  302.         iswbeg=1;        /* start at 1 */
  303.         iswval = TRUE;
  304.         if (clower(stemp[1]) == 'n' && clower(stemp[2]) == 'o')
  305.           {
  306.         iswval = FALSE ; iswbeg = 3 ;
  307.           }
  308.  
  309.         ch = clower(stemp[iswbeg]);        /* get the char */
  310.         if (ch == 'r')        /* read only access */
  311.         rdonly=iswval;
  312.         else if (ch == 'i')        /* auto indent */
  313.         autoin = iswval;
  314.         else if (ch == 'w')        /* word processing mode */
  315.           {
  316.         if (iswval)
  317.             wraplm = 70;
  318.         else
  319.             wraplm = 0;
  320.           }
  321.         else if (ch == 'l')        /* log file */
  322.         usebak = iswval;
  323.         else if (ch == 'b')
  324.         makebackup = iswval;    /* make a backup file */
  325.         else if (ch == 'z')
  326.         usecz = iswval;
  327.         else if (ch == 'o' && (stemp[iswbeg+1] == '=' ||
  328.           stemp[iswbeg+1] == ':'))    /* specifying output */
  329.           {
  330.         if (!iswval)        /* wrong order! */
  331.           {
  332.             remark("Bad -O= switch");
  333.             quit();
  334.           }
  335.         scopy(stemp,iswbeg+2,dest_file,0);  /* remember name */
  336.           }
  337.         else if (ch == 's')    /* big save buffer */
  338.           {
  339.         if (!iswval)
  340.             blimit=BUFFLIMIT;
  341.         else
  342.             blimit=BUFFLIMIT*3;
  343.           }
  344.         else if (ch == 'x' && (stemp[iswbeg+1] == '=' ||
  345.           stemp[iswbeg+1] == ':'))    /* specifying string to execute */
  346.           {
  347.         if (!iswval)        /* wrong order! */
  348.           {
  349.             remark("Bad -X= switch");
  350.             quit();
  351.           }
  352.         scopy(stemp,iswbeg+2,&rptbuf[0][0],0);  /* store command */
  353.         rptcnt[0] = 1;                /* execute once */
  354.         nxtrpt[0] = 0;                /* from beginning */
  355.           }
  356.         else if (ch >= '0' && ch <= '9')    /* making a virtual window */
  357.           {
  358.         tvlins = tvatoi(&stemp[iswbeg]);    /* get virtual screen size */
  359.         if (tvlins < 3 || tvlins > tvhardlines)    /* invalid window */
  360.           {
  361.             remark("Invalid window size");
  362.             tvlins = tvhardlines;
  363.           }
  364.         else
  365.           {
  366.             ddline = (tvlins / 2) + 1;    /* fix home line */
  367.             setdscrl();
  368.           }
  369.           }
  370.         else                /* illegal switch */
  371.           {
  372.         prompt("Unknown switch -"); ttwt(ch);
  373.         prompt(": Ignore and continue? (y/n) ");
  374.         ureply(rply,1);
  375.         if (*rply != 'Y')
  376.           {
  377.             reset();  quit();
  378.           }
  379.           }
  380.       }
  381.     else            /* must have a file name */
  382.       {
  383.         strcpy(orig_file,stemp);
  384.       }
  385.       }        /* end for */
  386.  
  387. /*    now open file properly - make copies to all 4 names */
  388.  
  389. GETNAME:
  390.     while (!*orig_file)
  391.       {
  392.         ask("Edit file? ",orig_file,FNAMESIZE);
  393.       }
  394.  
  395.     expand_name(orig_file);        /* expand on unix */
  396.  
  397.     if (!(infile = fopen(orig_file,FILEREAD)))    /* can open? */
  398.       {
  399.         prompt("Create file "); prompt(orig_file);
  400.         prompt("? (y/n) ");
  401.         ureply(rply,1);
  402.         if (*rply != 'Y')
  403.           {
  404.         *orig_file = 0; goto GETNAME;
  405.           }
  406.         if (*dest_file)
  407.         remark("New file, -o= switch ignored");
  408.         *dest_file = 0;
  409.         newfil = TRUE;        /* a new file */
  410.         rdonly = FALSE;
  411.       }
  412.  
  413. /* orig_file now has the name of the source file, and it might be open */
  414.  
  415.     ineof = FALSE;
  416.     strcpy(source_file,orig_file);    /* copy to other names */
  417.     if (!*dest_file)        /* no -o specified */
  418.         strcpy(dest_file,orig_file);
  419.     strcpy(work_file,dest_file);    /* use dest file for diff drives */
  420.  
  421.     if (!newfil)            /* not new file */
  422.       {
  423.         fclose(infile);        /* close orig file */
  424.         if (!(infile = fopen(source_file,FILEREAD)))    /* re-open */
  425.           {
  426.         remark("Internal editor error, aborting");
  427.         exit();
  428.           }
  429.         get_mode(infile);        /* get mode of original file */
  430.       }
  431.     else
  432.       {
  433.         *orig_file = *source_file = 0; 
  434.       }
  435.  
  436. /* now see if we can make an output file */
  437.     
  438.     if (!rdonly)
  439.       {
  440.         temp_name(work_file,TRUE);    /* make into a temporary name 1st time */
  441.         if ((outfile = fopen(work_file,FILEREAD)))
  442.           {
  443.         /* this code is needed when the temp_name might not be
  444.            unique - which happens when you push (^O) and try to
  445.            edit a file with the same main name but perhaps a different
  446.            extension - the temp file will be the same, and the child
  447.            version of tvx will then delete the temprorary file created
  448.            by the parent.  This can happen again if fbeg, but let's
  449.            assume the 'y' applies forever.
  450.         */
  451.         fclose(outfile);    /* close up the file */
  452.         prompt("Work file already exists: ");
  453.         remark(work_file);
  454.         prompt("Erase it and continue with editing? (y/n) ");
  455.         ureply(rply,1);
  456.         if (*rply != 'Y')
  457.           {
  458.             reset();
  459.             exit();        /* abnormal exit */
  460.           }
  461.           }
  462.  
  463.         unlink(work_file);    /* get rid if already there */
  464.  
  465.         if (!(outfile = fopen(work_file,FILEWRITE)))
  466.           {
  467.         prompt("Unable to create output work file: ");
  468.         remark(work_file);
  469.         if (!newfil)
  470.           {
  471.             prompt("Continue in read only mode? (y/n) ");
  472.             ureply(rply,1);
  473.             if (*rply != 'Y')
  474.               {
  475.             fclose(infile);
  476.             reset();
  477.             exit();        /* abnormal exit */
  478.               }
  479.           }
  480.         *dest_file = *work_file = 0;
  481.         rdonly = TRUE;
  482.           }
  483.       }
  484.     else
  485.       {
  486.         *dest_file = *work_file = 0;
  487.       }
  488.   }
  489.  
  490. /* =============================>>> setdscrl <<<============================= */
  491.   setdscrl()
  492.   {    /* compute a new value for dscrl */
  493.  
  494.     if (dscrl == 0)
  495.     return;            /* if already 0, don't change */
  496.     dscrl = tvlins / 3;
  497.     if ((ddline + dscrl) >= tvlins)    /* looks ugly if hits last line */
  498.     dscrl--;
  499.     if (dscrl < 0)        /* don't allow this */
  500.     dscrl = 0;
  501.   }
  502.  
  503. /* =============================>>> ADDFIL <<<============================= */
  504.   int addfil(rw)
  505.   int rw;
  506.   {  /* addfil - add contents of external file to save buffer
  507.     positive means read into buffer, negative means write save buffer */
  508.  
  509.     SLOW int chr;
  510.  
  511.     SLOW BUFFINDEX fromch;
  512.     SLOW int i;
  513.     SLOW FILE *f;
  514.  
  515.     if (rw >= 0)    /* read a file */
  516.       {
  517.     if (!gbgcol(nxtchr))    /* gc first */
  518.       {
  519.         newscr();
  520.         tverrb("No save room");
  521.         return (FALSE);
  522.       }
  523.  
  524.     tvclr();
  525. #ifdef LASL
  526.     ask("Read external filename: ",stemp,FNAMESIZE);
  527. #else
  528.     ask("Yank filename: ",stemp,FNAMESIZE);
  529. #endif
  530.  
  531.     expand_name(stemp);            /* expand on some systems */
  532.  
  533.     if (!(f = fopen(stemp,FILEREAD)) || !*stemp)
  534.       {
  535.         newscr();
  536. #ifdef LASL
  537.         tverrb(" Unable to open external file ");
  538. #else
  539.         tverrb(" Unable to open yank file ");
  540. #endif
  541.         return (FALSE);
  542.      }
  543.  
  544.     savlin=0 ; savlen=0 ; nxtsav = mxbuff ;    /* clear out save buffer */
  545.  
  546.  
  547.     do
  548.       {
  549.         if ((chr = getchr(f)) < 0)
  550.           {
  551.         newscr();
  552.         fclose(f);
  553.         return (TRUE);
  554.           }
  555.         if (chr == NEWLINE)
  556.           {
  557. #ifdef FILELF
  558.         getchr(f);
  559. #endif
  560.         chr=ENDLINE;
  561.         ++savlin;
  562.           }
  563.         *(buff+nxtsav--) = chr;
  564.         if ((nxtsav <= (nxtchr+ALMOSTOUT)) || (nxtsav < (mxbuff/2)))
  565.           {
  566.         newscr();
  567.         tverrb("File only partly read");
  568.         break;
  569.           }
  570.       }
  571.     while (1);
  572.     fclose(f);
  573.     return (TRUE);
  574.       }
  575.  
  576.     /* --------------- to here, then writing from save buffer --------------*/
  577.  
  578.  
  579.     if (nxtsav == mxbuff)        /* nothing to save */
  580.       {
  581.      tverrb("Save buffer empty!");
  582.     return (TRUE);
  583.       }
  584.  
  585.     tvclr();
  586.     ask("Write to external filename: ",stemp,FNAMESIZE);
  587.  
  588.     expand_name(stemp);            /* expand on some systems */
  589.  
  590.     if (!(f = fopen(stemp,FILEWRITE)) || !*stemp)
  591.       {
  592.     newscr();
  593.     tverrb(" Unable to open external file ");
  594.     return (FALSE);
  595.       }
  596.  
  597.     
  598. /*   # move down line to make space for new */
  599.     fromch = mxbuff;        /* where taking saved stuff from */
  600.     for (i = 0 ; i < savlin ; ++i)
  601.       {
  602.     for ( ; ; )        /* scan save buffer */
  603.       {
  604.          if ((chr = *(buff+fromch--)) == ENDLINE)
  605.           {
  606.         fputc(NEWLINE,f);
  607. #ifdef FILELF
  608.         fputc(LF,f);
  609. #endif
  610.         break;
  611.           }
  612.         else
  613.         fputc(chr,f);
  614.       }
  615.       }
  616.  
  617.     if (usecz)
  618.     fputc(ENDFILE,f);
  619.     fclose(f);
  620.     newscr();
  621.     return (TRUE);
  622.  
  623.   }
  624.  
  625. /*=============================>>> SCOPY  <<<================================*/
  626.   scopy(old,oldbeg,new,newbeg)
  627.   char old[], new[];
  628.   int oldbeg,newbeg;
  629.   {
  630.     while (old[oldbeg])
  631.     new[newbeg++]=old[oldbeg++];
  632.     new[newbeg] = 0;
  633.   }
  634.  
  635. /* **************************************************************************
  636.  
  637.     Following code is for non-unix systems
  638.  
  639.  **************************************************************************** */
  640. #ifndef UNIX
  641. /* =============================>>> get_mode <<<============================= */
  642.   get_mode(f)
  643.   FILE *f;
  644.   {        /* gets access mode of open file f */
  645.   }
  646.  
  647. /* =============================>>> set_mode <<<============================= */
  648.   set_mode(f)
  649.   FILE *f;
  650.   {        /* sets access mode of open file f */
  651.   }
  652.  
  653. /* ==========================>>> expand_name <<<============================ */
  654.   expand_name(n)
  655.   char *n;
  656.   {        /* expands unix file names */
  657.   }
  658.  
  659. /* =============================>>> ren_file <<<=========================== */
  660.   ren_file(old,new)
  661.   char *old, *new;
  662.   {
  663. #ifndef GEM_DOS
  664.     if (rename(old,new) != 0)
  665.       {
  666.     prompt(old) ; prompt(" not renamed to "); remark(new);
  667.     prompt("Edits found in "); remark(old);
  668.       }
  669. #endif
  670.  
  671. #ifdef GEM_DOS
  672. #ifdef MW_C
  673.     if (Frename(0,old,new) != 0)    /* can't find C version */
  674.       {
  675.     prompt(old) ; prompt(" not renamed to "); remark(new);
  676.     prompt("Edits found in "); remark(old);
  677.       }
  678. #else
  679.     FILE *temp;
  680.  
  681.     gemdos(0x56,0,old,new);    /* can't find C version */
  682.     if (!(temp = fopen(new,FILEREAD)))    /* see if it was successful */
  683.       {
  684.     prompt(old) ; prompt(" not renamed to "); remark(new);
  685.     prompt("Edits found in "); remark(old);
  686.       }
  687.     else
  688.     fclose(temp);
  689. #endif
  690. #endif
  691.   }
  692.  
  693. /* =============================>>> temp_name <<<=========================== */
  694.   temp_name(n,first)
  695.   char *n;
  696.   int first;
  697.   {
  698.     /* generates a temporary name from n.  Depending on value of
  699.        first, it will either add a 1 or 2 to name */
  700.  
  701.     SLOW int i;
  702.  
  703.     if (first)
  704.       {
  705.     if ((i = rindx(n,FILESEP)) > 0)    /* see if extenstion */
  706.         scopy(TEMPEXT,0,n,i);        /* make .bak */
  707.     else
  708.       {
  709.         scopy(TEMPEXT,0,n,strlen(n));    /* just add on */
  710.       }
  711.       }
  712.     else
  713.       {
  714.     i = strlen(n);
  715.     if (n[i-1] == '1')
  716.         n[i-1] = '2';
  717.     else
  718.         n[i-1] = '1';
  719.       }
  720.   }
  721. #endif
  722.  
  723. /* **************************************************************************
  724.  
  725.     This section is for the version supporting command logfile
  726.     backup.  The code necessary for this version is included here,
  727.     and may be compiled by defining VB to be a blank.
  728.  
  729.  **************************************************************************** */
  730.  
  731. /* =============================>>> OPNBAK <<<============================= */
  732.   opnbak()
  733.   { 
  734.     /* opnbak - open the backup log file
  735.        if VB defined as ' ', then backup version created */
  736.  
  737. #ifdef VB
  738.  
  739.     if (! usebak)
  740.       {
  741.     bakflg = FALSE;
  742.     return;
  743.       }
  744.  
  745.     bkuout = fopen(BACKUPNAME,FILEWRITE);
  746.     bakpos = 1;
  747. #endif
  748.  
  749.   }
  750.  
  751. /* =============================>>> PUTBAK <<<============================= */
  752.   putbak(chr)
  753.   char chr;
  754.   { /* putbak - put a character into the backup file */
  755.  
  756. #ifdef VB
  757.     static char copy;
  758.  
  759.     if (! usebak)
  760.     return;
  761.     copy=chr;
  762.     if (copy < 32 || copy == '@' || copy==delkey)
  763.       {
  764.     fputc('@',bkuout);
  765.     bakcrlf();
  766.     if (copy < 32)
  767.         copy += '@';
  768.     else if (copy==delkey)
  769.         copy = '?';     /* let @? be rubout */
  770.       }
  771.     fputc(copy,bkuout);
  772.     bakcrlf();
  773. #endif
  774.   }
  775.  
  776. #ifdef VB
  777. /* =============================>>> BAKCRLF <<<============================= */
  778.   bakcrlf()
  779.   {    /* conditionally put a cr/lf to backup file */
  780.  
  781.     if (++bakpos > 63)
  782.       {
  783.     fputc(NEWLINE,bkuout);
  784. #ifdef FILELF
  785.     fputc(LF,bkuout);
  786. #endif
  787.     bakpos = 1;
  788.       }
  789.   }
  790. #endif
  791.  
  792. /* =============================>>> CLOBAK <<<============================= */
  793.   clobak()
  794.   {
  795.  
  796. #ifdef VB
  797.     if (! usebak)
  798.     return;
  799.     fputc(NEWLINE,bkuout);
  800. #ifdef FILELF
  801.     fputc(LF,bkuout);
  802. #endif
  803.     if (usecz)
  804.     fputc(ENDFILE,bkuout);
  805.  
  806.     fclose(bkuout);
  807. #endif
  808.   }
  809.  
  810. /* =============================>>> GETBAK <<<============================= */
  811.   getbak(chr)
  812.   char *chr;
  813.   {  /* get one char from back up file if there */
  814.  
  815. #ifdef VB
  816.     SLOW int ich;
  817.  
  818. l10:
  819.     if ((ich = getchr(bkuin)) < 0 || ich == ENDFILE)
  820.       {
  821. l15:    fclose(bkuin);
  822.     *chr=0;            /* harmless character */
  823.     bakflg=FALSE;
  824.     verify(1);
  825.     return;
  826.       }
  827.     if (ich == NEWLINE)
  828.     goto l10;
  829. #ifdef FILELF
  830.     if (ich == LF)
  831.     goto l10;
  832. #endif
  833.     *chr=ich;
  834.     if (ich=='@')
  835.       {
  836. l20:    if ((ich = getchr(bkuin)) < 0 || ich == ENDFILE)
  837.       {
  838.         goto l15;
  839.       }
  840.     if (ich == NEWLINE)
  841.         goto l20;
  842. #ifdef FILELF
  843.     if (ich == LF)
  844.         goto l20;
  845. #endif
  846.     *chr=ich;
  847.     if (ich == '?')
  848.         *chr=delkey;
  849.     else if (*chr != '@')
  850.         *chr= ich - '@';
  851.       }
  852. #endif
  853.   }
  854.  
  855. /* =============================>>> OPNATF <<<============================= */
  856.   opnatf()
  857.   { /* open an indirect command file */
  858.  
  859. #ifdef VB
  860.  
  861.     tvclr();
  862.  
  863.     ask("Name of command file: ",stemp,FNAMESIZE);
  864.         /* read in the file name from the terminal */
  865.  
  866.     expand_name(stemp);
  867.  
  868.     if (!*stemp)
  869.       {
  870.     verify(1);
  871.     return;
  872.       }
  873.  
  874.     if (!(bkuin = fopen(stemp,FILEREAD)))
  875.       {
  876.     verify(1);
  877.     tverrb("Bad @ name");
  878.     return;
  879.       }
  880.     bakflg=TRUE;
  881.     newscr();
  882. #endif
  883.   }
  884.  
  885. /* **************************************************************************
  886.  
  887.     This section contains code to write and read buffers of data
  888.  
  889.  **************************************************************************** */
  890.  
  891. /* =============================>>> RDPAGE <<<============================= */
  892.   int rdpage()
  893.   { /* rdpage - read in file up to buffer limit
  894.        only place text read from edited file */
  895.  
  896.     SLOW int chr;
  897.     SLOW int newlns;
  898. #ifdef GETSIO
  899.     char inbuff[256];
  900.     FAST char *bp;    /* ptr to inbuff */
  901.     SLOW int do_read;    /* flag if need to read */
  902.  
  903.     do_read = TRUE;    /* need to do read first time */
  904. #endif
  905.  
  906.     if (newfil)        /* can't read in when a new file */
  907.       {
  908.     return (FALSE);
  909.       }
  910.     if (nxtlin > mxline || nxtchr > mxbuff-130)    /* error check */
  911.       {
  912.     tverrb("Lines filled ");
  913.     return (FALSE);
  914.       }
  915.  
  916.     newlns=0;            /* begin at the beginning */
  917.  
  918.     while (mxline-nxtlin > LINELIMIT  && nxtsav-nxtchr > blimit && !ineof)
  919.       {             /* read in while have room */
  920. #ifdef GETSIO
  921.     if (do_read)
  922.       {
  923.         if (fgets(inbuff,255,infile) == NULL)
  924.           {
  925.         ineof = TRUE;
  926.         break;
  927.           }
  928.         do_read = FALSE;    /* a line has been read */
  929.         bp = inbuff;    /* point to beginning of buffer */
  930.       }
  931.     chr = *bp++;        /* "read" the character */
  932. #else
  933.     if ((chr = fgetc(infile)) == EOF)
  934.       {
  935.         ineof = TRUE;
  936.         break;
  937.       }
  938. #endif
  939.  
  940.     if (chr == ENDFILE && usecz)
  941.       {
  942.         ineof = TRUE;
  943.         break;
  944.       }
  945. #ifdef FILELF
  946.     if (chr == LF)
  947.         continue;
  948. #endif
  949.     *(buff+nxtchr) = BEGLINE;
  950.     *(lines+nxtlin) = nxtchr++;
  951.     ++newlns ;
  952.         
  953.     while (chr != NEWLINE)        /* store a line */
  954.       {
  955.         *(buff+nxtchr++) = chr;
  956. #ifdef GETSIO
  957.         chr = *bp++;        /* "read" the character */
  958. #else
  959.         if ((chr = fgetc(infile)) == EOF)
  960.           {
  961.         ineof = TRUE;
  962.         break;
  963.           }
  964. #endif
  965.         if (chr == ENDFILE && usecz)
  966.           {
  967.         ineof = TRUE;
  968.         break;
  969.           }
  970.       }    /* end of while != NEWLINE */
  971. #ifdef GETSIO
  972.     do_read = TRUE;
  973. #endif
  974.  
  975.     *(buff+nxtchr++) = ENDLINE;
  976.     ++nxtlin;
  977.       }
  978.  
  979.     if (nxtlin > 1)        /* we really read something */
  980.       {
  981.     curlin=1;        /* point to top of char */
  982.     curchr = *(lines+1)+1;    /* point to first character */
  983.       }
  984.     return (newlns > 0) ;
  985.   }
  986.  
  987. /* =============================>>> WTPAGE <<<============================= */
  988.   wtpage(whow)
  989.   int whow;
  990.   { /* wtpage - write out contents of text buffer, and clear line list */
  991.  
  992.     FAST int i;
  993.     FAST char *chrp;
  994.     SLOW char *lim;
  995.     SLOW int wlimit;
  996. #ifdef GETSIO
  997.     char outbuff[256];
  998.     FAST char *bp;    /* ptr to outbuff */
  999.     SLOW int buff_len;
  1000. #endif
  1001.  
  1002.     if (whow < 0)        /* allow writing partial buffer */
  1003.     wlimit = curlin - 1;
  1004.     else
  1005.     wlimit = nxtlin -1;
  1006.  
  1007.     if (nxtlin <= 1 || rdonly)
  1008.       {
  1009.     tverr("Empty buffer");
  1010.     goto zapb;
  1011.       }
  1012.  
  1013.     if (whow < 0)
  1014.     tverr("Writing partial buffer");
  1015.     else
  1016.     tverr("Writing buffer");
  1017.  
  1018.     tvhdln();
  1019.  
  1020.     for (i = 1 ; i <= wlimit ; ++i)
  1021.       {
  1022.     chrp = buff + (*(lines+i)+1);    /* ptr to first char of line */
  1023. #ifdef GETSIO
  1024.     bp = outbuff;            /* pt to buffer */
  1025.     buff_len = 0;
  1026.     while (*chrp != ENDLINE && buff_len < 253)
  1027.       {
  1028.         *bp++ = *chrp++;        /* copy character */
  1029.       }
  1030.     *bp++ = NEWLINE;
  1031. #ifdef FILELF
  1032.     *bp++ = LF;
  1033. #endif
  1034.     *bp = 0;            /* end of string */
  1035.     fputs(outbuff,outfile);        /* and write all at once */
  1036. #else
  1037.     while (*chrp != ENDLINE)
  1038.       {
  1039.         fputc(*chrp++, outfile);
  1040.       }
  1041.     fputc(NEWLINE,outfile);
  1042. #ifdef FILELF
  1043.     fputc(LF,outfile);
  1044. #endif
  1045.  
  1046. #endif
  1047.       }
  1048.  
  1049. zapb:
  1050.  
  1051.     if (whow < 0)
  1052.       {
  1053.     killin(-(curlin-1));    /* kill to top of buffer */
  1054.     if (!gbgcol(nxtchr))    /* gc first */
  1055.       {
  1056.         newscr();
  1057.         tverrb("Warning: no extra room created");
  1058.         return (FALSE);
  1059.       }
  1060.     return (TRUE);
  1061.       }
  1062.     else
  1063.       {
  1064.     lim = buff + nxtsav;
  1065.     for (chrp=buff ; chrp < lim ; *chrp++ = GARBAGE)
  1066.         ;
  1067.     tvdlin =            /* start on first line again */
  1068.     nxtlin =            /* reset to initial state */
  1069.     nxtchr = 1;
  1070.     curchr =
  1071.     curlin=0;
  1072.     return (TRUE);
  1073.       }
  1074.   }
  1075.  
  1076. /* **************************************************************************
  1077.  
  1078.     This section contains misc. stuff likely to be operating system dependent
  1079.  
  1080.  **************************************************************************** */
  1081.  
  1082. /* ===========================>>> OPSYSTEM <<<============================== */
  1083.   opsystem()
  1084.   {
  1085. #ifdef MSDOS            /* !!! cii-86 dependent */
  1086.  
  1087.     char rp[80];
  1088.  
  1089. #ifdef CII_C
  1090. MS_AGAIN:
  1091.     tvclr();
  1092.     ask("DOS command (any key to resume edit when done): ",rp,79);
  1093.     remark("");
  1094.     if (system(rp) != 0)
  1095.       {
  1096.         tvxy(1,1);
  1097.     ask("Sorry, but couldn't find COMMAND.COM.◆",rp,1);
  1098.       }
  1099.     else
  1100.       {
  1101.     tvxy(1,1);
  1102.     ask("◆",rp,1);
  1103.     if (*rp == '!')
  1104.        goto MS_AGAIN;
  1105.       }
  1106. #endif
  1107.  
  1108. #ifdef MICROSOFT_C
  1109. #include <process.h>
  1110.     tvclr();
  1111.     remark("Spawning DOS, enter EXIT to return to TVX.");
  1112.     spawnlp(P_WAIT,"command.com","command",NULL);
  1113.     
  1114. #endif
  1115.     verify(1);
  1116. #endif
  1117.  
  1118. #ifdef UNIX
  1119.     unix_sys();
  1120. #endif
  1121.  
  1122. #ifdef GEM_DOS
  1123.     char rp[4];
  1124.     tvclr();
  1125.     ask("Call to OS not implemented, press any key to resume: ",rp,1);
  1126.  
  1127.     verify(1);
  1128. #endif
  1129.   }
  1130.  
  1131. #ifndef UNIX
  1132. #ifdef GEM_DOS
  1133. /* ===========================>>> TTINIT <<<============================== */
  1134.   ttinit()
  1135.   { /*  this routine could be used to set up keyboard input, perhaps
  1136.     turning on non-echoed input */
  1137.  
  1138.     if ((st_res = getres()) > 0)        /* get resolution */
  1139.       {
  1140.     tvhardlines = tvlins = st_res;
  1141.     ddline = (st_res / 2) + 1;        /* always 25, 40, or 50 */
  1142.       }
  1143.     return;
  1144.   }
  1145.  
  1146. /* ===========================>>> TTCLOS <<<============================== */
  1147.   ttclos()
  1148.   {  /* this routine could undo anything ttinit() did */
  1149.     char rp[4];
  1150.  
  1151.     if (st_res > 0 && st_res != getres())
  1152.       {
  1153.     remark("--- Resetting screen resolution ---");
  1154.     prompt("    Press any key to continue...");
  1155.     reply(rp,1);
  1156.     tvclr();
  1157.     switch (st_res)
  1158.       {
  1159.         case 25:            /* change to 25 */
  1160.         rez25();
  1161.         break;
  1162.  
  1163.         case 40:            /* change to 40 */
  1164.         rez50();        /* ugly, but gets rid of line */
  1165.         tvclr();
  1166.         rez40();
  1167.         break;
  1168.  
  1169.         case 50:            /* change to 50 */
  1170.         rez50();
  1171.         break;
  1172.  
  1173.         default:
  1174.         break;
  1175.       }
  1176.       }
  1177.  
  1178.     tvclr();
  1179.     return;
  1180.   }
  1181. #else
  1182. /* ===========================>>> TTINIT <<<============================== */
  1183.   ttinit()
  1184.   { /*  this routine could be used to set up keyboard input, perhaps
  1185.     turning on non-echoed input */
  1186.     return;
  1187.   }
  1188.  
  1189. /* ===========================>>> TTCLOS <<<============================== */
  1190.   ttclos()
  1191.   {  /* this routine could undo anything ttinit() did */
  1192.     return;
  1193.   }
  1194. #endif
  1195. #endif
  1196.  
  1197. #ifndef VTERM
  1198. /* ===========================>>> TTRD <<<============================== */
  1199.   ttrd()
  1200.   { /* this routine is called to read one unechoed char from the keyboard */
  1201.  
  1202.   static int tc, i;
  1203.   static char chr;
  1204.  
  1205. RDTOP:
  1206. #ifdef OSCPM
  1207.     while (!(tc = bdos(6,-1)))        /* cp/m implementation */
  1208.     ;
  1209. #endif
  1210.  
  1211. #ifdef MSDOS
  1212. #ifdef MICROSOFT_C
  1213.     tc = bdos(7,0,0) & 0377;        /* ms-dos implementation */
  1214. #endif
  1215. #ifdef CII_C
  1216.     tc = bdos(7,0) & 0377;        /* ms-dos implementation */
  1217. #endif
  1218. #endif
  1219.  
  1220. #ifdef GEM_DOS
  1221. #ifdef MW_C
  1222.     tc = (int) (Bconin(2) & 0x7f);
  1223. #else
  1224.     tc = (int) (bios(2,2) & 0x7f);        /* GEMDOS application */
  1225. #endif
  1226. #endif
  1227.  
  1228. #ifdef UNIX
  1229.     tc = ttrd_unix();
  1230. #endif
  1231.  
  1232.     chr = tc & 0377;
  1233.  
  1234. #ifdef MAPTICK 
  1235.     if (chr == '`')
  1236.       {
  1237.     return (27);        /* force ` to escape */
  1238.       }
  1239. #endif
  1240.  
  1241.     if (chr == funkey)            /* function key */
  1242.       {
  1243. #ifdef OSCPM
  1244.     while (!(tc = bdos(6,-1)))        /* cp/m implementation */
  1245.         ;
  1246. #endif
  1247.  
  1248. #ifdef MSDOS
  1249. #ifdef MICROSOFT_C
  1250.     tc = bdos(7,0,0) & 0377;        /* ms-dos implementation */
  1251. #endif
  1252. #ifdef CII_C
  1253.     tc = bdos(7,0) & 0377;        /* ms-dos implementation */
  1254. #endif
  1255. #endif
  1256.  
  1257. #ifdef GEM_DOS
  1258. #ifdef MW_C
  1259.     tc = (int) (Bconin(2) & 0x7f);
  1260. #else
  1261.     tc = (int) (bios(2,2) & 0x7f);        /* GEMDOS application */
  1262. #endif
  1263. #endif
  1264.  
  1265. #ifdef UNIX
  1266.     tc = ttrd_unix();
  1267. #endif
  1268.     chr = tc & 0377;
  1269.     for (i = 0 ; i < 50 && funchar[i] ; ++i)
  1270.       {
  1271.         if (chr == funchar[i])
  1272.           {
  1273.         tc = funcmd[i] & 0377;
  1274.         return (tc);
  1275.           }
  1276.       }
  1277.     goto RDTOP;            /* ignore invalid function keys */
  1278.       }
  1279.     tc = chr & 0377;
  1280.     return (tc);
  1281.  
  1282.   }
  1283. #endif
  1284.  
  1285. #ifndef UNIX
  1286. /* ===========================>>> TTWT <<<============================== */
  1287.   ttwt(chr)
  1288.   char chr;
  1289.   { /*  this routine is called to write one char to the keyboard
  1290.     It also interprets print direction */
  1291.  
  1292.     dispch(chr);    /* cp/m, ms-dos version */
  1293.     if (useprint)
  1294.     printc(chr);
  1295.   }
  1296. #endif
  1297.  
  1298. #ifdef MSDOS
  1299. #define DEFGETCHR
  1300. #endif
  1301.  
  1302. #ifdef OSCPM
  1303. #define DEFGETCHR
  1304. #endif
  1305.  
  1306. #ifdef GEM_DOS
  1307. #define DEFGETCHR
  1308. #endif
  1309.  
  1310. #ifdef DEFGETCHR
  1311. /* ===========================>>> GETCHR <<<============================== */
  1312.   getchr(filnum)
  1313.   FILE *filnum;
  1314.   {  /* get a character from filnum */
  1315.  
  1316. #define EOFBYTE 26
  1317.  
  1318.     FAST int ichr;
  1319.  
  1320. #ifdef MW_C
  1321.     if (((ichr = getc(filnum)) == EOFBYTE))
  1322. #else
  1323.     if (((ichr = fgetc(filnum)) == EOFBYTE))
  1324. #endif
  1325.       {
  1326.     if (usecz)
  1327.         return (EOF);
  1328.       }
  1329.  
  1330.     return (ichr);
  1331.   }
  1332. #endif
  1333.  
  1334. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1335.  
  1336.     TVX TERMINAL DRIVER  for various terminals
  1337.  
  1338.    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  1339.  
  1340.  
  1341. /* =============================>>> TRMINI <<<============================= */
  1342.   trmini()
  1343.   {  /* initialize term if necessary */
  1344.  
  1345.     sendcs(cinit);
  1346.     tvclr();
  1347.   }
  1348.  
  1349. /* =============================>>> reset <<<============================= */
  1350.   reset()
  1351.   {
  1352.     sendcs(cendit);
  1353.     ttclos();
  1354.   }
  1355.  
  1356. /* =============================>>> TVPLIN <<<============================= */
  1357.   tvplin(chrptr)
  1358.   BUFFINDEX chrptr;
  1359.   { /* tvplin - put line beginning at chrptr
  1360.         will only type what will fit on screen (using xout) */
  1361.  
  1362.     SLOW char tmp, *tptr;
  1363.     SLOW int linlen, origx;
  1364.     SLOW BUFFINDEX i;
  1365.  
  1366. #ifdef ULBD
  1367.     SLOW int ul, bd, useul, usebd;
  1368.  
  1369.     ul = bd = useul = usebd = FALSE;
  1370. #endif
  1371.  
  1372.     last_col_out = linptr = 0;
  1373.     origx = xoutcm;            /* save x so can get true linelen */
  1374.     for (i =  chrptr; *(buff+i)!=ENDLINE && xoutcm <= 240; ++i)
  1375.       {
  1376. #ifdef NO_EXTEND_CHAR
  1377.     if ((*(buff+i) < ' ' && *(buff+i) >= 0) || (*(buff+i) & 0x80) )
  1378.         /* control character? */
  1379. #else
  1380.     if (*(buff+i)<' ' && *(buff+i) >= 0)    /* control character? */
  1381. #endif
  1382.       {
  1383.         if (*(buff+i) == TAB)
  1384.           {
  1385.         if (tabspc > 0)
  1386.           {
  1387.             do 
  1388.               {
  1389.             linout[linptr++] = ' ';    /* replace with blanks */
  1390.             ++xoutcm;
  1391.               }
  1392.             while ( ((xoutcm-1) % tabspc) != 0);
  1393.           }
  1394.         else
  1395.           {
  1396.             linout[linptr++] = '^';
  1397.             linout[linptr++] = 'I';
  1398.             xoutcm += 2;
  1399.           }
  1400.         continue;
  1401.           }
  1402.         else        /*  other control character */
  1403.           {
  1404.         linout[linptr++] = (*(buff+i) & 0x80) ? '~' : '^';
  1405.         ++xoutcm;
  1406.         if (xoutcm==tvcols && *(buff+i) != ENDLINE)
  1407.             continue;
  1408.  
  1409. /*  #$$$    ascii machines!!!! */
  1410.         tmp = *(buff+i);
  1411.         if ((tmp &= 0x7f) < ' ')    /* ok to mix extended, ctrl */
  1412.             tmp += '@';
  1413.         linout[linptr++]=tmp;
  1414.  
  1415. #ifdef ULBD
  1416.         if ( *(buff+i)==TOGUNDERLINE && cundlb[0] != 0)
  1417.           {
  1418.             if (ul)
  1419.               {
  1420.             strcopy(cundle,0,linout,&linptr);
  1421.             ul = FALSE;
  1422.               }
  1423.             else
  1424.               {
  1425.             strcopy(cundlb,0,linout,&linptr);
  1426.             useul = TRUE;
  1427.             ul = TRUE;
  1428.               }
  1429.           }
  1430.         if (*(buff+i) == TOGBOLD && cboldb[0] != 0)
  1431.           {
  1432.             if (bd)
  1433.               {
  1434.             strcopy(cbolde,0,linout,&linptr);
  1435.             bd = FALSE;
  1436.               }
  1437.             else
  1438.               {
  1439.             strcopy(cboldb,0,linout,&linptr);
  1440.             usebd = TRUE;
  1441.             bd = TRUE;
  1442.               }
  1443.           }
  1444. #endif          
  1445.           }
  1446.       } /*# end if control character */
  1447.     else 
  1448.       {
  1449.         linout[linptr++] = *(buff+i);
  1450.       }
  1451.     ++xoutcm;
  1452.       }
  1453.  
  1454.     if (*(buff+chrptr-1) == BEGLINE)        /* write whole line */
  1455.       {
  1456.     last_col_out = linlen = mint(tvcols,linptr-leftmg+1);
  1457.     if (linlen > 0)
  1458.       {
  1459.         tvlout(&linout[leftmg-1],linlen);
  1460.       }
  1461.       }
  1462.     else
  1463.       {
  1464.     linlen = mint(tvcols-origx+1,linptr);
  1465.     last_col_out = linlen + origx - 1;
  1466.     if (linlen > 0)
  1467.         tvlout(linout,linlen);
  1468.       }
  1469. #ifdef ULBD
  1470.     if (useul)
  1471.     sendcs(cundle);
  1472.     if (usebd)
  1473.     sendcs(cbolde);
  1474. #endif
  1475.     
  1476.   }
  1477.  
  1478. /* =============================>>> TVLOUT <<<============================= */
  1479.   tvlout(chrbuf,lenbuf)
  1480.   char chrbuf[];
  1481.   int lenbuf;
  1482.   {  /* tvlout - intercepts tvcout calls to use line I/O */
  1483.  
  1484.     if (!(echof && !bakflg))
  1485.     return;
  1486.     ttwtln(chrbuf,lenbuf);    /* write out whole line */
  1487.   }
  1488.  
  1489. /* =============================>>> TVTYPE <<<============================= */
  1490.   tvtype(ibeg,icnt)
  1491.   int ibeg,icnt;
  1492.   { /* tytype - type icnt lines starting at lines[ibeg]
  1493.         no cr/lf on the last line */
  1494.  
  1495.     FAST int i,lim;
  1496.     SLOW BUFFINDEX start;
  1497.  
  1498.     if (!echof)
  1499.     return;
  1500.     xoutcm=tvx;
  1501.     lim = ibeg+icnt-1;
  1502.  
  1503.     for (i = ibeg ; i<=lim && i<nxtlin ; ++i)
  1504.       {
  1505.     start = (*(lines+i))+1;
  1506.     tvplin(start);    /* type out a line */
  1507.     xoutcm=1;
  1508.     if (celin[0] && last_col_out < tvcols)
  1509.         tvelin();    /* erase rest of line */
  1510.     if ( i != lim )
  1511.       {
  1512.         tvcout(CR);
  1513. #ifdef USELF
  1514.         tvcout(LF);
  1515. #endif
  1516.       }
  1517.       }
  1518. #ifdef SCR_BUF
  1519.     ttflush();
  1520. #endif
  1521.   }
  1522.  
  1523. /* =============================>>> SCRPRINT <<<============================= */
  1524.   scrprint()
  1525.   {    /* print screen on printer */
  1526.  
  1527. #ifndef UNIX
  1528.  
  1529.    SLOW beg, cnt;
  1530.  
  1531.     tvclr();        /* clear screen first */
  1532.     finddl(&beg, &cnt);
  1533.     useprint = TRUE;    /* enable printing */
  1534.     tvtype(beg,cnt);    /* and display/print */
  1535.     printc(CR);        /* force closing cr/lf */
  1536. #ifdef USELF
  1537.     printc(LF);
  1538. #endif
  1539.     useprint = FALSE;
  1540. #endif
  1541.     verify(1);        /* reset screen */
  1542.   }
  1543.  
  1544. /* =============================>>> VERIFY <<<============================= */
  1545.   verify(knt)
  1546.   int knt;
  1547.   { /* verify - rewrite the screen or type current line with cursor */
  1548.  
  1549.     SLOW int xf;
  1550.  
  1551.     newscr();
  1552.     xf = findx();
  1553.     tvxy(xf,tvy);    /* reset cursor to current position */
  1554. #ifdef SCR_BUF
  1555.     ttflush();
  1556. #endif
  1557.   }
  1558.  
  1559. /* =============================>>> CSRCMD <<<============================= */
  1560.   csrcmd()
  1561.   {
  1562.     ins_mode = FALSE;        /* let world know in command mode */
  1563.     sendcs(ccsrcm);
  1564. #ifdef SCR_BUF
  1565.     ttflush();
  1566. #endif
  1567.   }
  1568.  
  1569. /* =============================>>> CSRINS <<<============================= */
  1570.   csrins()
  1571.   {
  1572.     SLOW int oldx,oldy,oldxot;
  1573.  
  1574.     ins_mode = TRUE;        /* in insert mode */
  1575.     sendcs(ccsrin);
  1576.  
  1577.     if (tvdlin != tvhardlines)
  1578.       {
  1579.         oldx = tvx; oldy = tvy; oldxot = xoutcm;
  1580.     tvmsg("### Insert Mode ###");
  1581.     tvxy(oldx,oldy);
  1582.     xoutcm = oldxot;
  1583.       }
  1584. #ifdef SCR_BUF
  1585.     ttflush();
  1586. #endif
  1587.   }
  1588.   
  1589. /* **************************************************************************
  1590.  
  1591.    tv screen primitives follow
  1592.  
  1593. *************************************************************************** */
  1594.  
  1595. /* =============================>>> TVBOTB <<<============================= */
  1596.   tvbotb(n)
  1597.   int n;
  1598.   {  /* tvbotb - make n blank lines at the bottom of the screen */
  1599.  
  1600.     FAST int i,j;
  1601.  
  1602. /*  All versions  control sequences */
  1603.  
  1604.     if (n >= tvlins)
  1605.       {
  1606.     tvclr();
  1607.       }
  1608.     else 
  1609.       {
  1610.     tvxy(1,tvhardlines);    /* go to real last line */
  1611.     for (i = 1 ; i <= n ; ++i)    /* and write n blank lines */
  1612.       {
  1613.         sendcs(cbotb);
  1614.         if (dsp_mem)
  1615.         tvelin();    /* might scroll non-blank line */
  1616.       }
  1617.     j=tvlins-n+1;    /* home to virtual last line */
  1618.     tvxy(1,j);    /* position at first new blank line */
  1619.       }
  1620. #ifdef SCR_BUF
  1621.     ttflush();
  1622. #endif
  1623.   }
  1624.  
  1625. /* =============================>>> TVCLR  <<<============================= */
  1626.   tvclr()
  1627.   {  /* tvclr - clear the entire screen and home */
  1628.  
  1629.     if (cclears[0])
  1630.       {
  1631.     sendcs(cclears);
  1632.     tvx = tvy = 1;
  1633.       }
  1634.     else
  1635.       {
  1636.     tvxy(1,1);
  1637.     tvescr();
  1638.       }
  1639. #ifdef SCR_BUF
  1640.     ttflush();
  1641. #endif
  1642.   }
  1643.  
  1644. /* =============================>>> TVCOUT <<<============================= */
  1645.   tvcout(chr)
  1646.   char chr;
  1647.   {  /* tvcout - send one character to the terminal */
  1648.  
  1649.     if (echof && !bakflg)
  1650.     ttwt(chr);
  1651.   }
  1652.  
  1653. /* =============================>>> TVELIN <<<============================= */
  1654.   tvelin()
  1655.   {  /* tvelin - erase the rest of the current line */
  1656.  
  1657.     sendcs(celin);
  1658.   }
  1659.  
  1660. /* =============================>>> TVESCR <<<============================= */
  1661.   tvescr()
  1662.   {  /* tvescr - erase from current cursor position to end of screen */
  1663.  
  1664.     SLOW int oldx,oldy;
  1665.     FAST int i;
  1666.  
  1667.     if (cescr[0])
  1668.     sendcs(cescr);
  1669.     else
  1670.       {
  1671.     oldx = tvx ; oldy = tvy ;
  1672.     tvelin();
  1673.     for (i = oldy+1 ; i <= tvhardlines ; ++i)
  1674.       {
  1675.         tvxy(1,i);
  1676.         tvelin();
  1677.       }
  1678.     tvxy(oldx,oldy);
  1679.       }
  1680.   }
  1681.  
  1682. /* =============================>>> TVINSL <<<============================= */
  1683.   tvinsl()
  1684.   {  /* tvinsl - insert line, handle virtual screen size */
  1685.  
  1686.     SLOW int oldx,oldy;
  1687.  
  1688.     oldx = tvx ; oldy = tvy ;
  1689.     sendcs(ciline);
  1690.     if (tvlins != tvhardlines)
  1691.       {
  1692.     tvxy(1,tvlins+1);    /* kill scrolled down line */
  1693.     tvelin();
  1694.     tvxy(oldx,oldy);
  1695.       }
  1696.   }
  1697.  
  1698. /* =============================>>> TVTOPB <<<============================= */
  1699.   tvtopb(n)
  1700.   int n;
  1701.   {  /* tvtopb - create n blank lines at the top of the screen */
  1702.  
  1703.     FAST int i;
  1704.  
  1705.     if (! ctopb[0])
  1706.     return;
  1707.     tvxy(1,1);        /* home first */
  1708.     if ( n >= tvlins)
  1709.     tvescr();    /* simply erase the screen */
  1710.     else
  1711.       {
  1712.     for (i = 1 ; i <= n ; ++i)
  1713.       {
  1714.         sendcs(ctopb);
  1715.         if (dsp_mem)        /* non blank line might be scrolled */
  1716.         tvelin();
  1717.       }
  1718.     if (tvlins != tvhardlines)
  1719.       {
  1720.         tvxy(1,tvlins+1);    /* kill scrolled down line */
  1721.         tvelin();
  1722.         tvxy(1,1);
  1723.       }
  1724.       }
  1725.   }
  1726.  
  1727. /* =============================>>> TVXY   <<<============================= */
  1728.   tvxy(ix,iy)
  1729.   int ix,iy;
  1730.   {  /* tvxy - position cursor at position x,y 
  1731.         x=0 is left most column
  1732.         y=0 is top most line    */
  1733.  
  1734. #ifdef TERMCAP            /* TERMCAP different */
  1735.  
  1736.     tvx=ix;
  1737.     tvy=iy;
  1738.     tcapxy(ix,iy);        /* call termcap version of xy */
  1739.  
  1740. #else                /* generic version of tvxy */
  1741.  
  1742.     SLOW int x,y, coord1, coord2;
  1743.     SLOW char chrrep[4];
  1744.  
  1745.     x = mint(ix+addx,tvcols+addx);    /* column is addx */
  1746.     y = iy+addy;            /* same for row */
  1747.     tvx = ix;
  1748.     tvy = iy;
  1749.  
  1750.     sendcs(cxybeg);        /* opening control sequence */
  1751.     if (cxy1st == 'l')
  1752.       {
  1753.     coord1 = y ; coord2 = x;
  1754.       }
  1755.     else
  1756.       {
  1757.     coord1 = x ; coord2 = y;
  1758.       }
  1759.  
  1760.     if (cxychr)
  1761.       {
  1762.     tvitoa(coord1,chrrep);
  1763.     sendcs(chrrep);
  1764.       }
  1765.     else
  1766.     tvcout(coord1);
  1767.  
  1768.     sendcs(cxymid);        /* middle control sequence */
  1769.  
  1770.     if (cxychr)
  1771.       {
  1772.     tvitoa(coord2,chrrep);
  1773.     sendcs(chrrep);
  1774.       }
  1775.     else
  1776.     tvcout(coord2);
  1777.  
  1778.     sendcs(cxyend);        /* send terminating sequence */
  1779.  
  1780. #endif                /* end of gerneric version */
  1781.   }
  1782.  
  1783. /* =============================>>> SENDCS <<<============================= */
  1784.   sendcs(cs)
  1785.   char cs[];
  1786.   {    /* send a control sequencs to terminal */
  1787.  
  1788.     FAST int i;
  1789.  
  1790. #ifndef UNIX
  1791.  
  1792.     for (i = 0 ; cs[i] ; ++i)
  1793.     tvcout(cs[i]);
  1794. #else                /* unix version */
  1795.  
  1796. #ifdef TERMCAP            /* termcap uses special output */
  1797.     tcapcs(cs);            /* send control string to termcap */
  1798. #else
  1799.     i = strlen(cs);
  1800.     tvlout(cs,i);
  1801. #endif                /* terminal specific unix version */
  1802.  
  1803. #endif                /* end of unix version */
  1804.   
  1805.   }
  1806.  
  1807. /* =============================>>> GKBD   <<<============================= */
  1808.   gkbd(chr)
  1809.   char *chr;
  1810.   {  /* gkbd - get one character from the keyboard */
  1811.  
  1812. #ifdef VB
  1813.     if (!bakflg)
  1814.       {
  1815. #endif
  1816.     do 
  1817.       {
  1818.         *chr = ttrd();    /* read only if non-backup version */
  1819.       }
  1820.     while (*chr == 0);    /* ignore EOS character */
  1821. #ifdef VB
  1822.       }
  1823.     else
  1824.     getbak(chr);
  1825.     putbak(*chr);    /* save to backup file */
  1826. #endif
  1827.   }
  1828.  
  1829. #ifndef UNIX
  1830. /* =============================>>> TTWTLN <<<============================= */
  1831.   ttwtln(chrbuf,len)
  1832.   char chrbuf[];
  1833.   int len;
  1834.   {  /*  write one line to terminal, generic version, unix uses its own */
  1835.  
  1836.     FAST int i;
  1837.  
  1838.     for (i = 0 ; i < len ; i++)
  1839.     ttwt(chrbuf[i]);
  1840.   } 
  1841. #endif
  1842.  
  1843. #ifdef OSCPM
  1844. /* ===========================>>> DISPCH <<<============================== */
  1845.   dispch(chr)
  1846.   char chr;
  1847.   {
  1848.  
  1849.     bdos(2,chr);    /* cp/m, ms-dos version */
  1850.   }
  1851. /* =============================>>> USER_1 <<<============================= */
  1852.   user_1()
  1853.   {
  1854.     return (TRUE);
  1855.   }
  1856.  
  1857. /* =============================>>> USER_2 <<<============================= */
  1858.   user_2()
  1859.   {
  1860.     return (TRUE);
  1861.   }
  1862. #endif
  1863.  
  1864. #ifdef MSDOS
  1865. #ifndef IBMPC
  1866. /* ===========================>>> DISPCH <<<============================== */
  1867.   dispch(chr)
  1868.   char chr;
  1869.   {
  1870.  
  1871.     bdos(2,chr);    /* cp/m, ms-dos version */
  1872.   }
  1873. #endif
  1874. /* =============================>>> USER_1 <<<============================= */
  1875.   user_1()
  1876.   {
  1877.     return (TRUE);
  1878.   }
  1879.  
  1880. /* =============================>>> USER_2 <<<============================= */
  1881.   user_2()
  1882.   {
  1883.     return (TRUE);
  1884.   }
  1885. #endif
  1886.  
  1887. #ifdef GEM_DOS
  1888. /* ===========================>>> DISPCH <<<============================== */
  1889.   dispch(chr)
  1890.   char chr;
  1891.   {
  1892. #ifdef MW_C
  1893.     /* all this is necessary because of a bug in GEMDOS */
  1894.     while (Bcostat(2) == 0)    /* wait until ready */
  1895.       {
  1896.     if (Bconstat(2) != 0)    /* input waiting? */
  1897.         Bconin(2);        /* eat the chars */
  1898.       }
  1899.     Bconout(2,(int) chr);    /* out via bios */
  1900. #else
  1901.     while (!bios(8,2))        /* wait until ready */
  1902.       {
  1903.     if (bios(1,2))        /* input waiting? */
  1904.         bios(2,2);
  1905.       }
  1906.     bios(3,2,(int) chr);    /* out via bios */
  1907. #endif
  1908.   }
  1909.  
  1910. /* =============================>>> USER_1 <<<============================= */
  1911.   user_1(knt)
  1912.   int knt;
  1913.   {
  1914.     /* toggle screen res */
  1915.  
  1916.     if (st_res <= 0)
  1917.     return;
  1918.  
  1919.     tvclr();
  1920.     switch (knt)
  1921.       {
  1922.     case 25:            /* change to 25 */
  1923. SET25:
  1924.         rez25();
  1925.         tvhardlines = tvlins = 25;
  1926.         ddline = 13;
  1927.         break;
  1928.  
  1929.     case 40:            /* change to 40 */
  1930. SET40:
  1931.         rez50();        /* ugly, but gets rid of line */
  1932.         tvclr();
  1933.         rez40();
  1934.         tvhardlines = tvlins = 40;
  1935.         ddline = 21;
  1936.         break;
  1937.  
  1938.     case 50:            /* change to 50 */
  1939. SET50:
  1940.         rez50();
  1941.         tvhardlines = tvlins = 50;
  1942.         ddline = 26;
  1943.         break;
  1944.  
  1945.     default:
  1946.         if (st_res <= 0)    /* break if color */
  1947.         break;
  1948.         if (tvhardlines == 25)
  1949.         goto SET40;
  1950.         else if (tvhardlines == 40)
  1951.         goto SET50;
  1952.         else goto SET25;
  1953.       };
  1954.  
  1955.  
  1956.     setdscrl();            /* reset scroll region */
  1957.     tvidefs();            /* reset defaults */
  1958.     verify(1);
  1959.     return (TRUE);
  1960.   }
  1961.  
  1962. /* =============================>>> USER_2 <<<============================= */
  1963.   user_2(knt)
  1964.   int knt;
  1965.   {
  1966.     return (TRUE);
  1967.   }
  1968. #endif
  1969.